/*
 * TLD7002_OTP_Program.c
 *
 *  Created on: 2023��5��20��
 *      Author: CaiYingming
 */

/*******************************************************************************
 includes
 *******************************************************************************/
#include "TLD7002_OTP_Program.h"
/*******************************************************************************
 defines
 *******************************************************************************/

/*******************************************************************************
 global variables
 *******************************************************************************/

/*******************************************************************************
 local variables
 *******************************************************************************/
/* OTP configuration array, coming from file: example.ocfg */
uint16 OTP_hex_cfg_slave2[]= {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x034D, 0x034D, 0x034D,
0x034D, 0x034D, 0x034D, 0x034D, 0x134D, 0xFFFF, 0x8153, 0x0D4A, 0x0000, 0x2C2C, 0xFFFF, 0x0000,
0x0000, 0x808E, 0x0002, 0xC49F, 0x0008, 0x008C, 0x0000, 0x0000};

uint16 OTP_hex_cfg_slave1[]= {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x034D, 0x034D, 0x034D,
0x034D, 0x034D, 0x034D, 0x034D, 0x134D, 0xFFFF, 0x8153, 0x0D4A, 0x0000, 0x2C2C, 0xFFFF, 0x0000,
0x0000, 0x808E, 0x0001, 0xF4FC, 0x0008, 0x008C, 0x0000, 0x0000};

uint16 OTP_hex_cfg_common[40];

/*******************************************************************************
 global functions declare
 *******************************************************************************/

/*******************************************************************************
 local functions declare
 *******************************************************************************/

/*******************************************************************************
 global functions
 *******************************************************************************/

/*******************************************************************************
 local functions
 *******************************************************************************/

/*********************************************************************************************************
** Function name:       OTP_Cfg_Gen
** Descriptions:        OTP configuration array generate
** input parameters:    address: device address
** output parameters:   N/A
** Returned value:
*********************************************************************************************************/
void OTP_Cfg_Gen(uint16 address)
{
	uint16 device_address = address;
	uint8 i = 0;
	if(device_address == TLD7002_FRAME_SLAVE_ADDRESS_1)
	{
		for(i=0; i<40; i++)
			OTP_hex_cfg_common[i] = OTP_hex_cfg_slave1[i];
	}
	else if(device_address == TLD7002_FRAME_SLAVE_ADDRESS_2)
	{
		for(i=0; i<40; i++)
			OTP_hex_cfg_common[i] = OTP_hex_cfg_slave2[i];
	}
}


/*********************************************************************************************************
** Function name:       OTP_Read
** Descriptions:        OTP_Read PROCEDURE.
** input parameters:    N/A
** output parameters:   N/A
** Returned value:
*********************************************************************************************************/
bool OTP_Read(uint16 address, uint16 newInterfrDelay)
{
	uint8 res;
	bool ret= true;
	bool readBackMatch=true;
	TLD7002_PM_CHANGE_FRAME_t pmchange_TLD7002;
	TLD7002_READ_REG_DLC4_FRAME_t rregdl4_TLD7002;

	/* OTP configuration array generate */
	OTP_Cfg_Gen(address);

	/* Step1: send command PM_CHANGE_FRAME to INIT */
	TLD7002_TRX_PM_CHANGE(&pmchange_TLD7002, address, TLD7002_FRAME_PM_INIT_MODE);

	/*delay counted starting from the last bit transmitted*/
	us_Delay(newInterfrDelay);

	/* Step2: send command PM_CHANGE_FRAME twice to synchronize LLD library master rolling counter and TLD7002 rolling counter */
	TLD7002_TRX_PM_CHANGE(&pmchange_TLD7002, address, TLD7002_FRAME_PM_INIT_MODE);
	/* If the device under programming procedure never reaches the fail-safe state, the delay can be reduced to: delay > 1 ms */
	us_Delay(7005);

	/* Step3: set the TLD7002-16 in OTP mode */
	TLD7002_TRX_PM_CHANGE(&pmchange_TLD7002, address, TLD7002_FRAME_PM_OTP_MODE);
	us_Delay(1005);

	/* STEP4: read back the entire OTP, unified read lenght with read 5 times 8 word from the OTP and check*/
	for(int n =0;n<5;n++)
	{
		res = TLD7002_TRX_READ_REG_DLC4(&rregdl4_TLD7002, address, 0x83+n*8);
		us_Delay(newInterfrDelay);//wait interframe delay after TLD7002-16 answer
		if ( res == TLD7002_FRAME_VAL_NO_ERROR )
		{
			for (int i =0;i<8 ;i++ ) // lenght of DLC 6 is 16 words (TLD7002_LEN_WRITE_REG_DLC6_WRITE-TLD7002_LEN_WRITE_REG_OVHD)/2
			{
				if (rregdl4_TLD7002.r_read_reg.Data[i]!=OTP_hex_cfg_common[i+n*8] ) // compare readed OTP with written OTP cfg
				{
#ifdef USE_PRINTF
					printf("OTP wr: Err read Back Mismatch\r\n");
#endif
					ret= false;
					readBackMatch = false;
					break;
				}
			}
		}
		else
		{
#ifdef USE_PRINTF
			if(res == TLD7002_FRAME_VAL_UNDEFINED_ERROR)
				printf("OTP wr: Err readBack frame err ! An undefined error occurred copying the response in the frame!\r\n");
			else if(res == TLD7002_FRAME_VAL_COPY_FRAME_ERROR)
				printf("OTP wr: Err readBack frame err ! An error occurred at copying the response in the frame!\r\n");
			else if(res == TLD7002_FRAME_VAL_BROADCAST_ERROR)
				printf("OTP wr: Err readBack frame err ! The answer of an broadcast message cannot be validated!\r\n");
			else if(res == TLD7002_FRAME_VAL_CRC3_ERROR)
				printf("OTP wr: Err readBack frame err !  CRC3 error detected in response frame!\r\n");
			else if(res == TLD7002_FRAME_VAL_RC_ERROR)
				printf("OTP wr: Err readBack frame err ! Rolling Counter error detected in response frame!\r\n");
			else if(res == TLD7002_FRAME_VAL_CRC8_ERROR)
				printf("OTP wr: Err readBack frame err ! CRC8 error detected at data in response frame!\r\n");
#endif
			ret= false;
			readBackMatch = false;
			break;
		}
	}
#ifdef USE_PRINTF
	if (readBackMatch == true)
		printf("OTP wr: OTP readBack OK\r\n");
#endif

	/* Step5: send command PM_CHANGE_FRAME to INIT */
	TLD7002_TRX_PM_CHANGE(&pmchange_TLD7002, address, TLD7002_FRAME_PM_INIT_MODE);
	us_Delay(MAX(250+2*PWM_PERIOD_uS,newInterfrDelay));

	return ret;
}

/*********************************************************************************************************
** Function name:       OTP_Emulate
** Descriptions:        OTP_Emulate PROCEDURE 
** input parameters:    N/A
** output parameters:   N/A
** Returned value:
*********************************************************************************************************/
bool OTP_Emulate(uint16 address, uint16 newInterfrDelay)
{
	uint8 res;
	bool ret= true;
	bool readBackMatch=true;
	TLD7002_PM_CHANGE_FRAME_t pmchange_TLD7002;
	TLD7002_WRITE_REG_DLC1_FRAME_t wregdl1_TLD7002;
	TLD7002_WRITE_REG_DLC4_FRAME_t wregdl4_TLD7002;
	TLD7002_WRITE_REG_DLC7_FRAME_t wregdl7_TLD7002;
	TLD7002_HWCR_FRAME_t hwcr_TLD7002;
	TLD7002_READ_REG_DLC4_FRAME_t rregdl4_TLD7002;

	/* OTP configuration array generate */
	OTP_Cfg_Gen(address);

	/* ensure GPIN0 is LOW */
	PINS_DRV_WritePin(PORT_GPIN0, PIN_GPIN0, LOW);
	/* Step1: send command PM_CHANGE_FRAME to INIT */
	TLD7002_TRX_PM_CHANGE(&pmchange_TLD7002, TLD7002_FRAME_SLAVE_ADDRESS_BROADCAST, TLD7002_FRAME_PM_INIT_MODE);
	/*delay counted starting from the last bit transmitted*/
	us_Delay(1005);

	/* Step2: send command PM_CHANGE_FRAME twice to synchronize LLD library master rolling counter and TLD7002 rolling counter */
	TLD7002_TRX_PM_CHANGE(&pmchange_TLD7002, TLD7002_FRAME_SLAVE_ADDRESS_BROADCAST, TLD7002_FRAME_PM_INIT_MODE);
	/* If the device under programming procedure never reaches the fail-safe state, the delay can be reduced to: delay > 1 ms */
	us_Delay(7005);

	/*Step3: set interframe delay to 50us */
	TLD7002_TRX_WRITE_REG_DLC1(&wregdl1_TLD7002, TLD7002_FRAME_SLAVE_ADDRESS_BROADCAST, 0x3B, 0x000C);
	us_Delay(50);

	/* Step4: set the TLD7002-16 in OTP mode */
	TLD7002_TRX_PM_CHANGE(&pmchange_TLD7002, TLD7002_FRAME_SLAVE_ADDRESS_BROADCAST, TLD7002_FRAME_PM_OTP_MODE);
	us_Delay(1005);

	/* Step5: set GPIN0 HIGH to enable programming */
	PINS_DRV_WritePin(PORT_GPIN0, PIN_GPIN0, HIGH);
	us_Delay(50);

	/* Step6: write OTP Emulate passw(0x3BD2) in 0x80 */
	TLD7002_TRX_WRITE_REG_DLC1(&wregdl1_TLD7002, TLD7002_FRAME_SLAVE_ADDRESS_BROADCAST, 0x80, 0x3BD2);
	us_Delay(50);

	/* Step7: write first 32 words */
	TLD7002_TRX_WRITE_REG_DLC7(&wregdl7_TLD7002, TLD7002_FRAME_SLAVE_ADDRESS_BROADCAST, 0x83, OTP_hex_cfg_common);
	/* The time required to emulate is shorter than the one needed to write the OTP, so a standard interframe delay
     * after the WRITE_REG(DLC=7) is sufficient before next command is received.
     * From now on, the control unit uses the new OTP parameters (e.g. interframe delay and address) for the
     * communication with the device.
	 * */
	us_Delay(newInterfrDelay);

	/* Step8: Write last 8 words */
	TLD7002_TRX_WRITE_REG_DLC4(&wregdl4_TLD7002, TLD7002_FRAME_SLAVE_ADDRESS_BROADCAST, 0xA3, &OTP_hex_cfg_common[32]);
	us_Delay(newInterfrDelay);

	/* Step9: Set GPIN0 to low*/
	PINS_DRV_WritePin(PORT_GPIN0, PIN_GPIN0, LOW);
	us_Delay(newInterfrDelay);

	/*Step 10:*/
	TLD7002_TRX_HWCR_ALL(&hwcr_TLD7002, address);
	us_Delay(newInterfrDelay);

	/* STEP11 and Step 12: read back the entire OTP, unified read lenght with read 5 times 8 word from the OTP and check*/
	for(int n =0;n<5;n++)
	{
		res = TLD7002_TRX_READ_REG_DLC4(&rregdl4_TLD7002, address, 0x83+n*8);
		us_Delay(newInterfrDelay);//wait interframe delay after TLD7002-16 answer
		if ( res == TLD7002_FRAME_VAL_NO_ERROR )
		{
			for (int i =0;i<8 ;i++ ) // lenght of DLC 6 is 16 words (TLD7002_LEN_WRITE_REG_DLC6_WRITE-TLD7002_LEN_WRITE_REG_OVHD)/2
			{
				if (rregdl4_TLD7002.r_read_reg.Data[i]!=OTP_hex_cfg_common[i+n*8] ) // compare readed OTP with written OTP cfg
				{
#ifdef USE_PRINTF
					printf("OTP wr: Err read Back Mismatch\r\n");
#endif
					ret= false;
					readBackMatch = false;
					break;
				}
			}
		}
		else
		{
#ifdef USE_PRINTF
			if(res == TLD7002_FRAME_VAL_UNDEFINED_ERROR)
				printf("OTP wr: Err readBack frame err ! An undefined error occurred copying the response in the frame!\r\n");
			else if(res == TLD7002_FRAME_VAL_COPY_FRAME_ERROR)
				printf("OTP wr: Err readBack frame err ! An error occurred at copying the response in the frame!\r\n");
			else if(res == TLD7002_FRAME_VAL_BROADCAST_ERROR)
				printf("OTP wr: Err readBack frame err ! The answer of an broadcast message cannot be validated!\r\n");
			else if(res == TLD7002_FRAME_VAL_CRC3_ERROR)
				printf("OTP wr: Err readBack frame err !  CRC3 error detected in response frame!\r\n");
			else if(res == TLD7002_FRAME_VAL_RC_ERROR)
				printf("OTP wr: Err readBack frame err ! Rolling Counter error detected in response frame!\r\n");
			else if(res == TLD7002_FRAME_VAL_CRC8_ERROR)
				printf("OTP wr: Err readBack frame err ! CRC8 error detected at data in response frame!\r\n");
#endif
			ret= false;
			readBackMatch = false;
			break;
		}
	}
#ifdef USE_PRINTF
	if (readBackMatch == true)
		printf("OTP wr: OTP readBack OK\r\n");
#endif

	/* Step13: send command PM_CHANGE_FRAME to INIT */
	TLD7002_TRX_PM_CHANGE(&pmchange_TLD7002, address, TLD7002_FRAME_PM_INIT_MODE);
	us_Delay(MAX(250+2*PWM_PERIOD_uS,newInterfrDelay));

	/* STEP 14 check output status FAULT BIT */
	res = TLD7002_TRX_PM_CHANGE(&pmchange_TLD7002, address, TLD7002_FRAME_PM_INIT_MODE);
	if ( res == TLD7002_FRAME_VAL_NO_ERROR)
	{
		if (pmchange_TLD7002.r_power_mode_change.frame_termination.OST.OSB_FAULT== 0)
		{ // check if the OUTPUT STATUS byte FAULT bit is 0
#ifdef USE_PRINTF
			printf("OTP wr: OK FAULT=0\r\n");
#endif
		}
		else
		{
#ifdef USE_PRINTF
			printf("OTP wr: Err-OSB_FAULT=1\r\n");
#endif
			ret= false;
		}
	}
	else
	{
#ifdef USE_PRINTF
		if(res == TLD7002_FRAME_VAL_UNDEFINED_ERROR)
			printf("OTP wr: Err-frame2 ! An undefined error occurred copying the response in the frame!\r\n");
		else if(res == TLD7002_FRAME_VAL_COPY_FRAME_ERROR)
			printf("OTP wr: Err-frame2 ! An error occurred at copying the response in the frame!\r\n");
		else if(res == TLD7002_FRAME_VAL_BROADCAST_ERROR)
			printf("OTP wr: Err-frame2 ! The answer of an broadcast message cannot be validated!\r\n");
		else if(res == TLD7002_FRAME_VAL_CRC3_ERROR)
			printf("OTP wr: Err-frame2 !  CRC3 error detected in response frame!\r\n");
		else if(res == TLD7002_FRAME_VAL_RC_ERROR)
			printf("OTP wr: Err-frame2 ! Rolling Counter error detected in response frame!\r\n");
		else if(res == TLD7002_FRAME_VAL_CRC8_ERROR)
			printf("OTP wr: Err-frame2 ! CRC8 error detected at data in response frame!\r\n");
#endif
		ret= false;
	}
	return ret;
}

/*********************************************************************************************************
** Function name:       OTP_Write
** Descriptions:        OTP write PROCEDURE.
**                      Warning, working only on not written devices
** input parameters:    N/A
** output parameters:   N/A
** Returned value:
*********************************************************************************************************/
bool OTP_Write(uint16 address, uint16 newInterfrDelay)
{
	uint8 res;
	bool ret= true;
	bool readBackMatch=true;
	TLD7002_PM_CHANGE_FRAME_t pmchange_TLD7002;
	TLD7002_WRITE_REG_DLC1_FRAME_t wregdl1_TLD7002;
	TLD7002_WRITE_REG_DLC4_FRAME_t wregdl4_TLD7002;
	TLD7002_WRITE_REG_DLC7_FRAME_t wregdl7_TLD7002;
	TLD7002_HWCR_FRAME_t hwcr_TLD7002;
	TLD7002_READ_REG_DLC1_FRAME_t rregdl1_TLD7002;
	TLD7002_READ_REG_DLC4_FRAME_t rregdl4_TLD7002;

	/* OTP configuration array generate */
	OTP_Cfg_Gen(address);

	/* ensure GPIN0 is LOW */
	PINS_DRV_WritePin(PORT_GPIN0, PIN_GPIN0, LOW);
	/* Step1: send command PM_CHANGE_FRAME to INIT */
	TLD7002_TRX_PM_CHANGE(&pmchange_TLD7002, TLD7002_FRAME_SLAVE_ADDRESS_BROADCAST, TLD7002_FRAME_PM_INIT_MODE);
	/*delay counted starting from the last bit transmitted*/
	us_Delay(1005);

	/* Step2: send command PM_CHANGE_FRAME twice to synchronize LLD library master rolling counter and TLD7002 rolling counter */
	TLD7002_TRX_PM_CHANGE(&pmchange_TLD7002, TLD7002_FRAME_SLAVE_ADDRESS_BROADCAST, TLD7002_FRAME_PM_INIT_MODE);
	us_Delay(1005);

	/*Step3: set interframe delay to 50us */
	TLD7002_TRX_WRITE_REG_DLC1(&wregdl1_TLD7002, TLD7002_FRAME_SLAVE_ADDRESS_BROADCAST, 0x3B, 0x000C);
	us_Delay(50);

	/* Step4: set the TLD7002-16 in OTP mode */
	TLD7002_TRX_PM_CHANGE(&pmchange_TLD7002, TLD7002_FRAME_SLAVE_ADDRESS_BROADCAST, TLD7002_FRAME_PM_OTP_MODE);
	us_Delay(1005);

	/* Step5: set GPIN0 HIGH to enable programming */
	PINS_DRV_WritePin(PORT_GPIN0, PIN_GPIN0, HIGH);
	us_Delay(50);

	/* Step6: write OTP Programming passw(0xA478) in 0x81 */
	TLD7002_TRX_WRITE_REG_DLC1(&wregdl1_TLD7002, TLD7002_FRAME_SLAVE_ADDRESS_BROADCAST, 0x81, 0xA47B);
	us_Delay(50);

	/* Step7: write first 32 words */
	TLD7002_TRX_WRITE_REG_DLC7(&wregdl7_TLD7002, TLD7002_FRAME_SLAVE_ADDRESS_BROADCAST, 0x83, OTP_hex_cfg_common);
	us_Delay(17500);

	/* Step8: Write last 8 words */
	TLD7002_TRX_WRITE_REG_DLC4(&wregdl4_TLD7002, TLD7002_FRAME_SLAVE_ADDRESS_BROADCAST, 0xA3, &OTP_hex_cfg_common[32]);
	us_Delay(5000); // wait 5ms, OTP write is slow

	/* Step9: Set GPIN0 to low*/
	PINS_DRV_WritePin(PORT_GPIN0, PIN_GPIN0, LOW);
	us_Delay(50);

	/*Step 10:*/
	TLD7002_TRX_PM_CHANGE(&pmchange_TLD7002, TLD7002_FRAME_SLAVE_ADDRESS_BROADCAST, TLD7002_FRAME_PM_INIT_MODE);
	us_Delay(MAX(newInterfrDelay, 205)); //delay shall be:delay > 200us or bigger than the just configured interfr.del

	/* Step 11:*/
	TLD7002_TRX_HWCR_ALL(&hwcr_TLD7002, address); //First TRX command with device address!=broadcast, result is probably bad becasue RC is not sync with Device drivers library
	us_Delay(newInterfrDelay); //wait > new programmed interframe delay

	/* Step 12 read OTP_STATUS register */
	res = TLD7002_TRX_READ_REG_DLC1(&rregdl1_TLD7002, address, TLD7002_OTP_STATUS);
	us_Delay(newInterfrDelay); // wait > new programmed interframe delay
	if ( res == TLD7002_FRAME_VAL_NO_ERROR ) // received frame is valied
	{
		if(rregdl1_TLD7002.r_read_reg.Data[0] == 0x03) // OTP_STATUS is as expected for correct OTP write
		{
#ifdef USE_PRINTF
			printf("OTP wr: OTP_STATUS OK = 0x03, is in OTP programming mode!\r\n");
#endif
		}
		else
		{
#ifdef USE_PRINTF
			printf("OTP wr: err OTP_STATUS=0x%x\r\n", rregdl1_TLD7002.r_read_reg.Data[0]);
#endif
			ret= false;
		}
	}
	else
	{
#ifdef USE_PRINTF
		if(res == TLD7002_FRAME_VAL_UNDEFINED_ERROR)
			printf("OTP wr: Err frame1 ! An undefined error occurred copying the response in the frame!\r\n");
		else if(res == TLD7002_FRAME_VAL_COPY_FRAME_ERROR)
			printf("OTP wr: Err frame1 ! An error occurred at copying the response in the frame!\r\n");
		else if(res == TLD7002_FRAME_VAL_BROADCAST_ERROR)
			printf("OTP wr: Err frame1 ! The answer of an broadcast message cannot be validated!\r\n");
		else if(res == TLD7002_FRAME_VAL_CRC3_ERROR)
			printf("OTP wr: Err frame1 !  CRC3 error detected in response frame!\r\n");
		else if(res == TLD7002_FRAME_VAL_RC_ERROR)
			printf("OTP wr: Err frame1 ! Rolling Counter error detected in response frame!\r\n");
		else if(res == TLD7002_FRAME_VAL_CRC8_ERROR)
			printf("OTP wr: Err frame1 ! CRC8 error detected at data in response frame!\r\n");
#endif
		ret= false;
	}

	/* Step13: set the TLD7002-16 in OTP mode */
	TLD7002_TRX_PM_CHANGE(&pmchange_TLD7002, address, TLD7002_FRAME_PM_OTP_MODE);
	us_Delay(newInterfrDelay); // the interframe shall be counted starting from the last bit transmitted from the TLD7002-16 (slave response)

	/* STEP14 and Step 15: read back the entire OTP, unified read lenght with read 5 times 8 word from the OTP and check*/
	for (int n =0;n<5;n++)
	{
		res = TLD7002_TRX_READ_REG_DLC4(&rregdl4_TLD7002, address, 0x83+n*8);
		us_Delay(newInterfrDelay);//wait interframe delay after TLD7002-16 answer
		if ( res == TLD7002_FRAME_VAL_NO_ERROR )
		{
			for (int i =0;i<8 ;i++ ) // lenght of DLC 6 is 16 words (TLD7002_LEN_WRITE_REG_DLC6_WRITE-TLD7002_LEN_WRITE_REG_OVHD)/2
			{
				if (rregdl4_TLD7002.r_read_reg.Data[i]!=OTP_hex_cfg_common[i+n*8] ) // compare readed OTP with written OTP cfg
				{
#ifdef USE_PRINTF
					printf("OTP wr: Err read Back Mismatch\r\n");
#endif
					ret= false;
					readBackMatch = false;
					break;
				}
			}
		}
		else
		{
#ifdef USE_PRINTF
			if(res == TLD7002_FRAME_VAL_UNDEFINED_ERROR)
				printf("OTP wr: Err readBack frame err ! An undefined error occurred copying the response in the frame!\r\n");
			else if(res == TLD7002_FRAME_VAL_COPY_FRAME_ERROR)
				printf("OTP wr: Err readBack frame err ! An error occurred at copying the response in the frame!\r\n");
			else if(res == TLD7002_FRAME_VAL_BROADCAST_ERROR)
				printf("OTP wr: Err readBack frame err ! The answer of an broadcast message cannot be validated!\r\n");
			else if(res == TLD7002_FRAME_VAL_CRC3_ERROR)
				printf("OTP wr: Err readBack frame err !  CRC3 error detected in response frame!\r\n");
			else if(res == TLD7002_FRAME_VAL_RC_ERROR)
				printf("OTP wr: Err readBack frame err ! Rolling Counter error detected in response frame!\r\n");
			else if(res == TLD7002_FRAME_VAL_CRC8_ERROR)
				printf("OTP wr: Err readBack frame err ! CRC8 error detected at data in response frame!\r\n");
#endif
			ret= false;
			readBackMatch = false;
			break;
		}
	}
#ifdef USE_PRINTF
	if (readBackMatch == true)
		printf("OTP wr: OTP readBack OK\r\n");
#endif
	/* STEP 16 check output status FAULT BIT */
	/* wait for 2 PWM periods from the last HWCR command, CRC is checked 1 per PWM period, this is the worst case
	 * time needed from the TLD7002-16 to highlight eventual CRC errors on the OUTPUT STATUS BYTE
	 * */
	us_Delay(2*PWM_PERIOD_uS);
	/* dummy read reg, to obtain the OUTPUT STATUS BYTE reply back */
	res = TLD7002_TRX_READ_REG_DLC1(&rregdl1_TLD7002, address, TLD7002_OTP_STATUS);
	if ( res == TLD7002_FRAME_VAL_NO_ERROR)
	{
		if (rregdl1_TLD7002.r_read_reg.frame_termination.OST.OSB_FAULT== 0)
		{ // check if the OUTPUT STATUS byte FAULT bit is 0
#ifdef USE_PRINTF
			printf("OTP wr: OK FAULT=0\r\n");
#endif
		}
		else
		{
#ifdef USE_PRINTF
			printf("OTP wr: Err-OSB_FAULT=1\r\n");
#endif
			ret= false;
		}
	}
	else
	{
#ifdef USE_PRINTF
		if(res == TLD7002_FRAME_VAL_UNDEFINED_ERROR)
			printf("OTP wr: Err-frame2 ! An undefined error occurred copying the response in the frame!\r\n");
		else if(res == TLD7002_FRAME_VAL_COPY_FRAME_ERROR)
			printf("OTP wr: Err-frame2 ! An error occurred at copying the response in the frame!\r\n");
		else if(res == TLD7002_FRAME_VAL_BROADCAST_ERROR)
			printf("OTP wr: Err-frame2 ! The answer of an broadcast message cannot be validated!\r\n");
		else if(res == TLD7002_FRAME_VAL_CRC3_ERROR)
			printf("OTP wr: Err-frame2 !  CRC3 error detected in response frame!\r\n");
		else if(res == TLD7002_FRAME_VAL_RC_ERROR)
			printf("OTP wr: Err-frame2 ! Rolling Counter error detected in response frame!\r\n");
		else if(res == TLD7002_FRAME_VAL_CRC8_ERROR)
			printf("OTP wr: Err-frame2 ! CRC8 error detected at data in response frame!\r\n");
#endif
		ret= false;
	}
	return ret;
}

/*********************************************************************************************************
** Function name:       TLD7002_TRX_READ_REG_DLC1
** Descriptions:        combined TX and RX READ_REG_DLC1 function,
**                      with correct wait time in order to receive the entire TLD7002-16 reply
**
** input parameters:    N/A
** output parameters:   N/A
** Returned value:
*********************************************************************************************************/
uint8 TLD7002_TRX_READ_REG_DLC1(TLD7002_READ_REG_DLC1_FRAME_t* frame, uint8 addr, uint8 regStartAdd)
{
	TLD7002_TX_READ_REG_DLC1_FRAME(&TLD7002Network, frame, addr,regStartAdd);// read OTP status register
	us_Delay(TLD7002_LEN_READ_REG_DLC1_READ*BYTE_TIME_uS); // wait > data from TLD7002-16 to be available
	return TLD7002_RX_READ_REG_DLC1_FRAME(&TLD7002Network, frame);// send and receive twice to syncronize the LLD receiver rolling counter
}

/*********************************************************************************************************
** Function name:       TLD7002_TRX_READ_REG_DLC4
** Descriptions:        combined TX and RX READ_REG_DLC4 function,
**                      with correct wait time in order to receive the entire TLD7002-16 reply
**
** input parameters:    N/A
** output parameters:   N/A
** Returned value:
*********************************************************************************************************/
uint8 TLD7002_TRX_READ_REG_DLC4(TLD7002_READ_REG_DLC4_FRAME_t* frame, uint8 addr, uint8 regStartAdd)
{
	TLD7002_TX_READ_REG_DLC4_FRAME(&TLD7002Network, frame, addr, regStartAdd);// read OTP status register
	us_Delay(TLD7002_LEN_READ_REG_DLC4_READ*BYTE_TIME_uS); // wait > data from TLD7002-16 to be available
	return TLD7002_RX_READ_REG_DLC4_FRAME(&TLD7002Network, frame);// send and receive twice to syncronize the LLD receiver rolling counter
}

/*********************************************************************************************************
** Function name:       TLD7002_TRX_PM_CHANGE
** Descriptions:
** input parameters:    N/A
** output parameters:   N/A
** Returned value:
*********************************************************************************************************/
uint8 TLD7002_TRX_PM_CHANGE(TLD7002_PM_CHANGE_FRAME_t* frame, uint8 addr, TLD7002_FRAME_POWER_MODE_CHANGE_t mode)
{
	TLD7002_TX_PM_CHANGE_FRAME(&TLD7002Network, frame, addr, mode);
	us_Delay(TLD7002_LEN_PM_CHANGE_READ*BYTE_TIME_uS); // wait > data from TLD7002-16 to be available
	return TLD7002_RX_PM_CHANGE_FRAME(&TLD7002Network, frame);
}

/*********************************************************************************************************
** Function name:       TLD7002_TRX_WRITE_REG_DLC7
** Descriptions:
** input parameters:    N/A
** output parameters:   N/A
** Returned value:
*********************************************************************************************************/
uint8 TLD7002_TRX_WRITE_REG_DLC7(TLD7002_WRITE_REG_DLC7_FRAME_t* frame, uint8 addr, uint8 regStartAdd, uint16* data)
{
	TLD7002_TX_WRITE_REG_DLC7_FRAME(&TLD7002Network, frame, addr, regStartAdd, data);
	us_Delay(TLD7002_LEN_WRITE_REG_READ*BYTE_TIME_uS); // wait > data from TLD7002-16 to be available
	return TLD7002_RX_WRITE_REG_DLC7_FRAME(&TLD7002Network, frame);
}

/*********************************************************************************************************
** Function name:       TLD7002_TRX_WRITE_REG_DLC4
** Descriptions:
** input parameters:    N/A
** output parameters:   N/A
** Returned value:
*********************************************************************************************************/
uint8 TLD7002_TRX_WRITE_REG_DLC4(TLD7002_WRITE_REG_DLC4_FRAME_t* frame, uint8 addr, uint8 regStartAdd, uint16* data)
{
	TLD7002_TX_WRITE_REG_DLC4_FRAME(&TLD7002Network, frame, addr, regStartAdd, data);
	us_Delay(TLD7002_LEN_WRITE_REG_READ*BYTE_TIME_uS); // wait > data from TLD7002-16 to be available
    return TLD7002_RX_WRITE_REG_DLC4_FRAME(&TLD7002Network, frame);
}

/*********************************************************************************************************
** Function name:       TLD7002_TRX_WRITE_REG_DLC1
** Descriptions:
** input parameters:    N/A
** output parameters:   N/A
** Returned value:
*********************************************************************************************************/
uint8 TLD7002_TRX_WRITE_REG_DLC1(TLD7002_WRITE_REG_DLC1_FRAME_t* frame, uint8 addr, uint8 regStartAdd, uint16 data)
{
	TLD7002_TX_WRITE_REG_DLC1_FRAME(&TLD7002Network, frame, addr, regStartAdd, data);// write OTP write password in 0x81
	us_Delay(TLD7002_LEN_WRITE_REG_READ*BYTE_TIME_uS); // wait > data from TLD7002-16 to be available
	return TLD7002_RX_WRITE_REG_DLC1_FRAME(&TLD7002Network, frame);
}

/*********************************************************************************************************
** Function name:       TLD7002_TRX_HWCR_ALL
** Descriptions:
** input parameters:    N/A
** output parameters:   N/A
** Returned value:
*********************************************************************************************************/
uint8 TLD7002_TRX_HWCR_ALL(TLD7002_HWCR_FRAME_t* frame, uint8 addr)
{
	TLD7002_TX_HWCR_ALL_FRAME(&TLD7002Network, frame, addr);
	us_Delay(TLD7002_LEN_HWCR_READ*BYTE_TIME_uS); // wait > data from TLD7002-16 to be available
	return TLD7002_RX_HWCR_FRAME(&TLD7002Network, frame);
}

/*********************************************************************************************************
  End Of File
*********************************************************************************************************/
